#import <stdio.h>
#import <appkit/appkit.h>
#import <sys/file.h>
#import <syslog.h>


/*
 * receiptfilter
 * A tool for keeping an eye on read receipts that Mail.app 
 * automatically generates.
 *
 * Use:
 *  Install this program as, say, /usr/local/lib/receiptfilter.
 *  Start Mail.app.
 *  In Mail.app's Preferences panel, choose "Expert" and change
 *  the "Mailer:" field to "/usr/local/lib/receiptfilter".
 *
 * Now, every time Mail.app automatically tries to send a read receipt
 * to someone letting them know that you've just read their message,
 * an alert panel will pop up saying
 *   "Send a receipt to shayman@Objectario.com?"
 * and you can say "OK" or "No".
 *
 * How it Works:
 * 
 * This program is installed as the Mailer for Mail.app, meaning that
 * all outgoing mail is handed to this program for delivery.  Normally
 * your Mailer is "/usr/lib/sendmail".  If you change it to this program,
 * it will check all the outgoing mail and if it finds a line like
 * this
 *    Subject: Read Receipt
 * it will pop up the alert panel.  If you answer "No", this program
 * merely exits and no receipt is sent.  
 * If you answer "Yes", or if the original message didn't look like
 * a read receipt, the message is given to /usr/lib/sendmail in the
 * normal way and off it goes.
 *
 * Mail.app invokes the mailer program with the recipient or recipients
 * on the command line, and the message itself on standard input.
 * So this program copies the message from standard in to a temporary
 * file, and watches for the "Subject: Read Receipt" line as it
 * performs the copy.  When it comes time to send the message, this program
 * arranges that the temporary file it created is standard input, and then
 * executes "/usr/lib/sendmail" with the original argument list, so the
 * message is delivered in the normal way.
 *
 * Downside:
 *  - this program makes (and later deletes) a copy of every outgoing message
 *    you send in /tmp, so it will take a tiny bit longer to deliver a
 *    message, and some disk space will be used during delivery.
 *  - if your normal Mail.app mailer program is something other than
 *   /usr/lib/sendmail, you'll have to change this program to invoke
 *   the correct "real" mailer.
 *  - it might screw up if your mail message contains a single line longer
 *    than 1024 characters, but I don't think Mail.app generates lines
 *    like that.
 *  - this program checks both the header of the message and the text itself
 *    for the telltale "Subject: Read Receipt" line.  It should just
 *    check the header, I guess.
 *
 * Use at your own risk.
 *
 * Future Enhancements:
 *
 * I suppose this could be enhanced in a few ways.  Make it configurable
 * so that certain people (your friends) always get read receipts, others
 * never get read receipts, etc etc.
 *
 * It could install itself nicely.  Maybe you run "receiptfilter -install"
 * and it would set the Mail.app default automatically, and it would take
 * note of what mailer you were previously using rather than assuming
 * it was /usr/lib/sendmail.  
 *
 * Maybe a nice GUI for installation etc etc.
 *
 * Maybe this introductory comment could be shorter than the actual
 * source code itself :-)
 *
 * Comments and suggestions are welcome.
 * Steve Hayman
 * shayman@Objectario.com
 *
 */

/*
 * $Version$
 * $Log:	receiptfilter.m,v $
 * Revision 1.1  94/01/06  13:02:54  shayman
 * Initial revision
 * 
 * Revision 1.1  94/01/06  13:01:34  shayman
 * Initial revision
 * 
 */
 
main(argc, argv)
int argc;
char *argv[];
{

    char *dest = argv[1];
    int scratch;
    FILE *f;
    char tempfile[] = "/tmp/receiptfilter.XXXXXX";
    char linebuf[1024];	// hope for no lines longer than this in the msg
    BOOL isReceipt = NO;

    /*
     * in case we need to report any errors, they'll be sent via
     * syslog at priority "daemon.err", and should show up on the console.
     */
     
    openlog("receiptfilter", LOG_CONS|LOG_PID, LOG_DAEMON);

    [Application new];
    
    /*
     * Copy stdin to a temp file (and make sure it goes away
     * when we're through with it); look for the telltale
     * "Subject: Read Receipt\n" line.
     */
    scratch = mkstemp(tempfile);
    unlink(tempfile);	

    
    /*
     * read lines from stdin; write to temp file.
     */
    while ( fgets(linebuf, sizeof(linebuf)-1, stdin) ) {
    	write(scratch, linebuf, strlen(linebuf));
	
	if ( strcmp(linebuf, "Subject: Read Receipt\n") == 0 ) 
	    isReceipt = YES;
	
    }
    
    /*
     * Rewind scratch file; close stdin; dup scratch file.
     * Effect is that the scratch file is our process's new stdin.
     */
    lseek( scratch, 0, L_SET );
    close(0);
    dup(scratch);
    
    /*
     * If this message was a return receipt, give the user a chance
     * to confirm whether it should be sent or not.
     */
    if ( isReceipt ) {
	switch (
	    NXRunAlertPanel("Read Receipt", "Send a read receipt to %s?",
		    "OK", "No", NULL,dest) ) {
	case NX_ALERTALTERNATE:	/* No */

	    /*
	     * Exit immediately without calling sendmail.
	     */
	    exit(0);
	case NX_ALERTDEFAULT:	/* OK */
	default:
	    break;
	}

    }
    /*
     * run sendmail, let it pick up our arguments and standard input.
     *
     * If your *original* Mail.app mailer was something other than
     * /usr/lib/sendmail, change this line.
     */
    execv( "/usr/lib/sendmail", argv );

    /*
     * shouldn't get here.
     */
    syslog(LOG_ERR, "Couldn't execute /usr/lib/sendmail.");
    
    exit(0);
}
